/**
 * 
 */
package commons.base.netty.http;

import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.regex.Pattern;

/**
 * http uri路由
 * @author yuan<cihang.yuan@happyelements.com>
 * @since 1.7
 */
public class HttpRouter {

	private Map<String, NettyHttpServlet> router = new HashMap<String, NettyHttpServlet>();
	private PriorityQueue<Pattern> fuzzyUrlQueue = new PriorityQueue<Pattern>(new Comparator<Pattern>(){
		@Override
		public int compare(Pattern o1, Pattern o2) {
			if(o1.pattern().split("\\/").length > o2.pattern().split("\\/").length){
				return -1;
			}else if(o1.pattern().split("\\/").length < o2.pattern().split("\\/").length){
				return 1;
			}
			return 0;
		}});
	
	public void init() throws Exception{
		for(NettyHttpServlet servlet : router.values()){
			servlet.init();
		}
	}
	
	public void shutdown(){
		for(NettyHttpServlet servlet : router.values()){
			servlet.destroy();
		}
	}
	
	public void addServlet(String uri, NettyHttpServlet servlet){
		router.put(uri, servlet);
		
		if(uri.endsWith("*")){
			fuzzyUrlQueue.add(Pattern.compile(uri));
			
		}
	}
	
	public NettyHttpServlet getServlet(String uri){
		// 先精确匹配
		if(router.containsKey(uri)){
			return router.get(uri);
		}
		
		// 最长路径匹配
		return maxLengthPathMatch(uri);
	}
	
	/**
	 * 最长路径匹配
	 * @param uri
	 * @return
	 */
	private NettyHttpServlet maxLengthPathMatch(String uri){
		Iterator<Pattern> it = fuzzyUrlQueue.iterator();
		while(it.hasNext()){
			Pattern p = it.next();
			if(p.matcher(uri).matches()){
				return router.get(p.pattern());
			}
		}
		
		return null;
	}
}
